/**
 * @project name:crm
 */
package com.yunbo.crm.service.impl;

import com.yunbo.crm.base.BaseServiceImpl;
import com.yunbo.crm.dao.UserMapper;
import com.yunbo.crm.model.UserModel;
import com.yunbo.crm.pojo.User;
import com.yunbo.crm.query.UserQuery;
import com.yunbo.crm.service.UserService;
import com.yunbo.crm.utils.AssertUtil;
import com.yunbo.crm.utils.Md5Util;
import com.yunbo.crm.utils.PhoneUtil;
import com.yunbo.crm.utils.UserIDBase64;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * @Author : yun&bo
 * @CreateDate : ==>2021/1/19 23:40
 * @ClassName : ==>
 * @Description : ==>
 * @Version
 */
@Service
public class UserServiceImpl extends BaseServiceImpl<User, Integer> implements UserService {

    @Resource
    private UserMapper userMapper;

    /**
     * @param userName
     * @param pwd
     * @return
     */
    @Override
    public UserModel userLogin(String userName, String pwd) {
        /*  1.判断是否为空  */
        checkUserParams(userName, pwd);

        /* 2.调用持久层方法，通过用户名查询对象 */
        User user = userMapper.queryUserByUserName(userName);
        /* 3.判断用户对象是否为空*/
        AssertUtil.isTrue(user == null, "用户不存在!");
        /* 4.将前台传递的密码与数据库中查询的密码作比较 */
        checkUserPwd(pwd, user.getUserPwd());
        /* 构建用户模型并返回 */
        UserModel userModel = buildUserModel(user);

        return userModel;
    }

    /**
     * 验证参数是否为空
     *
     * @param userName
     * @param userPwd
     */
    private void checkUserParams(String userName, String userPwd) {
        AssertUtil.isTrue(StringUtils.isBlank(userName), "用户名称不能为空!");
        AssertUtil.isTrue(StringUtils.isBlank(userPwd), "用户密码不能为空!");
    }

    /**
     * 验证密码是否和数据库中一致
     *
     * @param userPwd
     */
    private void checkUserPwd(String pwd, String userPwd) {
        userPwd = Md5Util.encode(userPwd);
        AssertUtil.isTrue(pwd.equals(userPwd), "密码不正确!");
    }

    /**
     * 构建UserModel
     */
    private UserModel buildUserModel(User user) {
        UserModel newUserModel = new UserModel();
        //得到加密后的用户ID
        newUserModel.setUserIdStr(UserIDBase64.encoderUserID(user.getRowId()));
        newUserModel.setTrueName(user.getTrueName());
        newUserModel.setUserName(user.getUserName());
        return newUserModel;
    }


    /**
     * 更新用户密码
     */
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    @Override
    public void updateUserPwd(Integer userId, String userPwd, String newPwd, String repeatPwd) {
        //通过用户ID查询用户对象
        User user = userMapper.selectByPrimaryKey(userId);

        AssertUtil.isTrue(user == null, "用户不存在");

        //参数校验
        checkUserPwdParams(userPwd, newPwd, repeatPwd, user.getUserPwd());

        // 修改改密码
        user.setUserPwd(Md5Util.encode(newPwd));

        // 修改时间
        user.setUpdateDate(new Date());

        //进行更新 得到受影响的行数
        AssertUtil.isTrue(userMapper.updateByPrimaryKeySelective(user) != 1, "修改密码失败！");

    }

    /**
     * 修改密码参数验证
     *
     * @param userPwd   原始密码
     * @param newPwd    新密码
     * @param repeatPwd 重复密码
     * @param pwd       数据库中密码
     */
    private void checkUserPwdParams(String userPwd, String newPwd, String repeatPwd, String pwd) {
        AssertUtil.isTrue(StringUtils.isBlank(userPwd), "原始密码不能为空！");
        AssertUtil.isTrue(!pwd.equals(Md5Util.encode(userPwd)), "密码不正确");
        AssertUtil.isTrue(StringUtils.isBlank(newPwd), "新密码不能为空！");
        AssertUtil.isTrue(pwd.equals(Md5Util.encode(newPwd)), "新密码与最近设置的密码不能相同");
        AssertUtil.isTrue(StringUtils.isBlank(repeatPwd), "重复密码不能为空");
        AssertUtil.isTrue(!newPwd.equals(repeatPwd), "两次输入密码不一致");
    }

    /**
     * 查询所有销售人员
     *
     * @return
     */
    @Override
    public List<Map<String, Object>> queryAllSales() {
        List<Map<String, Object>> listContainMap = userMapper.queryAllSales();
        return listContainMap;
    }

    /**
     * 模糊查询用户
     *
     * @param userQuery
     * @return
     */
    @Override
    public Map<String, Object> userList(UserQuery userQuery) {
        return queryByParamsForTable(userQuery);
    }

    /**
     * 添加用户
     *
     * @param user
     */
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    @Override
    public void saveUser(User user) {
        checkParams(user);
        User temp = userMapper.queryUserByUserName(user.getUserName());
        AssertUtil.isTrue((null != temp && temp.getActiveFlag() == 1), "用户已存在");
        user.setActiveFlag(1);
        user.setUpdateDate(new Date());
        user.setCreateDate(new Date());
        user.setUserPwd(Md5Util.encode("123456"));
        AssertUtil.isTrue(insertSelective(user) < 1, "用户添加失败!");
    }

    /**
     * 更新用户
     * 当 新旧名字不相等 并且 库里存在 且库中元素为有效时 则报错
     * 当 新旧名字不相等/不相等      库里不存在 则成功
     *
     * @param user
     * @param request
     */
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    @Override
    public void updateUser(User user, HttpServletRequest request) {
        AssertUtil.isTrue(user.getRowId() == null, "用户更新异常");
        checkParams(user);
        User item = userMapper.selectByPrimaryKey(user.getRowId());
        AssertUtil.isTrue(null == item, "修改用户不存在");

        AssertUtil.isTrue(!user.getUserName().equals(item.getUserName())
                && userMapper.queryUserByUserName(user.getUserName())
                .getUserName().equals(user.getUserName())
                && item.getActiveFlag() == 1, "该用户名已存在");

        user.setUpdateDate(new Date());
        user.setUpdateBy(getLoginUserName(request));
        AssertUtil.isTrue(userMapper.updateByPrimaryKeySelective(user) < 1, "用户更新失败");
    }

    /**
     * 删除用户
     *
     * @param ids
     */
    @Override
    public void deleteUserByIds(Integer[] ids) {
        AssertUtil.isTrue((null == ids || ids.length < 0), "请选择要删除的数据");
        AssertUtil.isTrue(deleteBatch(ids) != ids.length, "删除失败");
    }

    /**
     * 添加用户参数验证
     * 用户名称
     * 用户邮箱地址
     * 用户手机号
     */
    private void checkParams(User user) {
        AssertUtil.isTrue(StringUtils.isBlank(user.getUserName()), "用户名不能为空");
        AssertUtil.isTrue(StringUtils.isBlank(user.getEmail()), "用户邮箱不能为空");
        AssertUtil.isTrue(!PhoneUtil.isMobile(user.getPhone()), "手机号格式不正确");
    }

}
